/**
 * @TimerMgr.as
 *
 * @author sodaChen mail:asframe@qq.com
 * @version 1.0
 * <br>Copyright (C), 2010-2015 asFrame.com
 * <br>This program is protected by copyright laws.
 * <br>Program Name:ASFrame
 * <br>Date:2016-5-11
 */
package com.asframe.mgr
{
	import com.asframe.pool.FactoryObjectPool;
	import com.asframe.pool.IObjectPool;
	import com.asframe.pool.impl.TimerFactoryImpl;
	import com.asframe.utils.FunctionUtils;

	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;

	/**
	 * Time管理器，实现了时间的管理
	 * @author sodaChen
	 * Date:2016-5-11
	 */
	public class TimeMgr
	{
		/** timer对象池 **/
		private static var timerPool			:IObjectPool = new FactoryObjectPool(new TimerFactoryImpl(),20);
		/** 防止重复添加 **/
		private static var funcToTimerDic		:Dictionary = new Dictionary();
		private static var timerDic			:Dictionary = new Dictionary();
		private static var funcListDic			:Dictionary = new Dictionary();
		private static var paramsDic			:Dictionary = new Dictionary();
		private static var isRunning			:Boolean = false;
		private static var removeList			:Vector.<Function> = new Vector.<Function>();
//		private static var countDic:Dictionary = new Dictionary();

		public static function hasDelay(fun:Function):Boolean
		{
			return funcToTimerDic[fun] != null;
		}
		/**
		 * 延时指定时间调用函数，是无限循环的，必须手动进行删除
		 * @param delay 延迟时间(毫秒)
		 * @param func 回调函数
		 * @param params 参数
		 *
		 */
		public static function addDelay(delay:int,
										fun:Function,
										params:* = null) : void
		{
			//添加这里有个问题，就是有可能是在一个回调函数里，调用了停止，也就是removefunc，但是因为在循环中，所以被放在
			//删除列表中，但是那个回调函数接着又把他添加回来，所以会产生再次存放到这里带的，结果重复的bug，有待修复和解决
			if (funcToTimerDic[fun] != null)
			{
				//此函数已存在，需先移除才能再添加
				throw new Error(FunctionUtils.getFuncName(fun) + "已经添加过该函数，请先移除");
			}
			if(params != null)
			{
				paramsDic[fun] = params;
			}
//			countDic[fun] = count;
			createTimer(delay);
			funcToTimerDic[fun] = delay;
			funcListDic[delay].push(fun);
		}
		/**
		 * 移除指定函数调用
		 * @param func
		 */
		public static function removeDelay(func:Function) : void
		{
			if (funcToTimerDic[func] == null)
			{
				return;
			}

			if(isRunning)
			{
				removeList.push(func);
				return ;
			}

			var timer:Timer = null;
			var tdelay:int = funcToTimerDic[func];
			delete funcToTimerDic[func];
			//删除target
			delete paramsDic[func];

			//todo [TimeMgr]可以优化城dic集合来处理会快些
			var tlist:Array = funcListDic[tdelay];
			var index:int = tlist.indexOf(func);
			if(index > -1)
			{
				tlist.splice(index, 1);
				if(tlist.length == 0)
				{
					timer = timerDic[tdelay] as Timer;
					timer.removeEventListener(TimerEvent.TIMER, timerHandler);
					timer.removeEventListener(TimerEvent.TIMER_COMPLETE, timerHandler);
					delete funcListDic[tdelay];
					delete timerDic[tdelay];
					//回收
					timerPool.returnObject(timer);
				}
			}
		}

		/** 时间监听处理函数 */
		protected static function timerHandler(event:TimerEvent) : void
		{
			isRunning = true;
			var tlist:Array = funcListDic[Timer(event.target).delay];
			var len:int = tlist.length;
			var fun:Function = null;
			for (var i:int = 0; i < len; i++)
			{
				fun = tlist[i];
				if(fun.length == 1)
				{
					fun(paramsDic[fun]);
				}
				else
				{
					fun();
				}
			}
			isRunning = false;
			if(removeList.length > 0)
			{
				for each (fun in removeList)
				{
					removeDelay(fun);
				}
				removeList.length = 0;
			}
		}

		/** 创建Timer实例 */
		private static function createTimer(delay:int) : Timer
		{
			if(timerDic[delay] == null)
			{
				var timer:Timer = timerDic[delay] = timerPool.borrowObject();
				timer.delay = delay;
				timer.addEventListener(TimerEvent.TIMER, timerHandler,false,0,true);
				timer.start();
				if(funcListDic[delay] == null)
				{
					funcListDic[delay] = [];
				}
			}
			return timerDic[delay];
		}
	}
}